import _ from "lodash";

/**
 * controller.js的getViewModel()方法里发的请求最终是在该文件的query方法里发出请求的
 */
function Loader(controller, api) {
  var allowInfinite = true;
  var allowLoopQuery = false;
  // 类型后缀
  var index = api.index;
  var prefix = (index == undefined || index == 0 || index == '') ? "" : "$" + index;

  // 类型，list、list$1、list$2... ，form、form$1、form$2等，没有$0
  this.getType = function () {
    return api.type + prefix;
  };

  // 初始化的参数，可把start，length和url后面的查询参数覆盖
  this.getInitParams = function () {
    console.log(prefix)
    return controller.context["initParams" + prefix] || {};
  };

  // search变量里的参数，变为请求参数后格式为：query[xxx] = yyy
  this.getSearch = function () {
    return controller.context["search" + prefix] || {};
  };

  // 发送请求的方法
  this.query = function (conditions) {
    if (!controller || !api.url) {
      return false;
    }
    conditions = _.extend({}, controller.$f7route.query, conditions);
    if (typeof controller["query" + prefix] == "function") {
      return controller["query" + prefix](this.getType(), conditions);
    }
    var self = this;
    var params = conditions;
    if (api.type == "list") {
      // 列表查询的一些参数，前面的start和length可以通过初始化参数覆盖
      params = _.extend({
          start: 0,
          length: 10,
          draw: 1
        },
        self.getInitParams(), {
          query: self.getSearch()
        },
        _.isString(conditions) ? {} : conditions
      );
      if (!allowInfinite) {
        params.start =
          controller.context["query" + prefix].startIndex *
          params.length;
      }
      if (allowLoopQuery) {
        var start = controller.context["query" + prefix].startIndex * params.length;
        var total = controller.context["query" + prefix].recordsTotal;
        params.start =
          start + params.length >= total ? 0 : start + params.length;
      }
    }

    // 请求前操作
    controller.onBeforeQuery(this.getType(), conditions, params);
    return new Promise((rs, rj) => {
      // 利用Framework7提供的request库请求接口，出于安全起见都用post请求
      if (api.method.toLowerCase() === 'get') {
        controller.$f7.request.get(api.url, params,
          function (result) {
            if (typeof controller.afterQuery == "function") {
              controller.afterQuery(self.getType(), true, result, rs, rj);
            } else {
              self.afterQuery(true, result, rs, rj);
            }
          },
          function (result) {
            if (typeof controller.afterQuery == "function") {
              controller.afterQuery(self.getType(), false, result, rs, rj);
            } else {
              self.afterQuery(false, result, rs, rj);
            }
          },
          "json"
        );
      } else if (api.method.toLowerCase() === 'post') {
        controller.$f7.request.post(api.url, params,
          function (result) {
            if (typeof controller.afterQuery == "function") {
              controller.afterQuery(self.getType(), true, result, rs, rj);
            } else {
              self.afterQuery(true, result, rs, rj);
            }
          },
          function (result) {
            if (typeof controller.afterQuery == "function") {
              controller.afterQuery(self.getType(), false, result, rs, rj);
            } else {
              self.afterQuery(false, result, rs, rj);
            }
          },
          "json"
        );
      }
    });
  };

  // 请求后操作
  this.afterQuery = function (isSuccess, result, resolve, reject) {
    var self = this;
    // 做一些数据适配
    if (typeof controller.adaptData == "function") {
      result = controller.adaptData(self.getType(), isSuccess, result);
    }
    if (typeof controller.onAfterQuery == "function") {
      // onAfterQuery，提供给页面重写
      result = controller.onAfterQuery(self.getType(), isSuccess, result);
    }
    if (!isSuccess || !result || (result instanceof XMLHttpRequest && result.status != 200)) {
      reject();
    } else {
      if (api.type == "list") {
        if (result.data && result.data.length > 0) {
          _.each(result.data, function (t) {
            // 列表数据做一些转换操作
            controller.onConvertItem(self.getType(), t);
          });
        }

        if (!allowInfinite) {
          // 滚动加载的情况下把新的列表数据追加在以前的后面
          var infiniteResult = controller.context["query" + prefix];
          infiniteResult.startIndex = result.startIndex;
          infiniteResult.data = _.concat(infiniteResult.data, result.data);
          resolve(buildResult(infiniteResult));
        } else {
          resolve(buildResult(result));
        }
      } else {
        resolve(result);
      }
    }
  };

  this.infinite = function () {
    var self = this;
    if (allowInfinite) {
      var listModel = controller.context["query" + prefix];
      if (listModel.data.length >= listModel.recordsTotal) {
        // controller.$f7.dialog.toast("已全部加载完毕");
        controller.context.allLoaded = true;
      } else {
        controller.context.allLoaded = false;
        allowInfinite = false;
        controller.$(".infinite-scroll-preloader").show();
        self.query(null).then(
          value => {
            controller.bind(value);
            controller.$f7.preloader.hide();
            controller.$(".infinite-scroll-preloader").hide();
            allowInfinite = true;
            var length = listModel.data.length,
              pageSize = listModel.pageSize;
            if (
              controller.listOptions.groupFormat &&
              length > pageSize
            ) {
              let $title = controller.$(
                `[data-api.type='${this.getType()}'] ul li.list-group-title`
              );
              $title.remove();
              var $li = controller.$(
                `[data-api.type='${this.getType()}'] ul li`
              );
              for (var i = pageSize; i < length; i++) {
                if (i % pageSize == 1) {
                  var title = controller.listOptions.groupFormat.format(
                    i,
                    Math.min(i + pageSize, length)
                  );
                  controller
                    .$$(
                      '<li class="list-group-title">' +
                      title +
                      "</li>"
                    )
                    .insertBefore($li[i - 1]);
                }
              }
            }
          },
          function (e) {
            allowInfinite = true;
            controller.$f7.dialog.toast("请求失败，请稍后重试");
            console.error(e);
          }
        );
      }
    }
  };

  this.loopQuery = function () {
    var self = this;
    if (!allowLoopQuery) {
      allowLoopQuery = true;
      self.query(null).then(
        function (value) {
          controller.bind(value);
          window.setTimeout(function () {
            allowLoopQuery = false;
          }, 2000);
        },
        function () {
          controller.$f7.dialog.toast("请求失败，请稍后重试");
        }
      );
    }
  };

  this.refresh = function () {
    return this.query(null).then(
      function (value) {
        controller.bind(value);
        controller.$f7.preloader.hide();
      },
      function () {
        controller.$f7.dialog.toast("请求失败，请稍后重试");
      }
    );
  };

  function buildResult(result) {
    var r = {};
    r["query" + prefix] = result;
    return r;
  }
}

export default Loader;
